package org.octopus.lee.provider;

import java.lang.reflect.InvocationTargetException;


import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.ServiceConfig;

/**
 * Created by Christian on 2016/12/9 用来初始化Dubbo提供方Service
 */
public class DubboProviderUtil {

	private String address;
	
	private String organization;
	
	private Integer protocolPort;
	
	private Integer protocolThreads;

	private static final String DEFAULT_VERSION = "1.0.0";

	private static final String APPLICATION_NAME_PREFIX = "Serv_";
	
	public void setAddress(String address) {
		this.address = address;
	}

	public void setOrganization(String organization) {
		this.organization = organization;
	}

	public void setProtocolPort(Integer protocolPort) {
		this.protocolPort = protocolPort;
	}

	public void setProtocolThreads(Integer protocolThreads) {
		this.protocolThreads = protocolThreads;
	}

	/**
	 * @param S
	 *            接口类型
	 * @param I
	 *            接口的实例化类型
	 * @param group
	 *            dubbo group
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	@SuppressWarnings("unchecked")
	public <S, I> void exportService(Class<S> S, Class<I> I, String group)
			throws InstantiationException, IllegalAccessException {
		
		// 服务实现
		S implementService = (S) I.newInstance();
		try {
			implementService.getClass().getMethod("setGroupId", String.class).invoke(implementService, group);
		} catch (NoSuchMethodException ex) {

		} catch (IllegalArgumentException e) {
		} catch (InvocationTargetException e) {
		} catch (SecurityException e) {
		}
		

		// 当前应用配置
		ApplicationConfig application = new ApplicationConfig();
		application.setOrganization(organization);
		application.setName(APPLICATION_NAME_PREFIX + group);
		application.setOwner(group);

		// 连接注册中心配置
		RegistryConfig registry = new RegistryConfig();
		registry.setAddress(address);

		// 服务提供者协议配置
		ProtocolConfig protocol = new ProtocolConfig();
		protocol.setName("dubbo");
		protocol.setPort(protocolPort);
		protocol.setThreads(protocolThreads);

		// 注意：ServiceConfig为重对象，内部封装了与注册中心的连接，以及开启服务端口

		// 服务提供者暴露服务配置
		ServiceConfig<S> service = new ServiceConfig<S>(); // 此实例很重，封装了与注册中心的连接，请自行缓存，否则可能造成内存和连接泄漏
		service.setApplication(application);
		service.setRegistry(registry); // 多个注册中心可以用setRegistries()
		service.setProtocol(protocol); // 多个协议可以用setProtocols()
		service.setInterface(S);
		service.setRef(implementService);
		service.setVersion(DEFAULT_VERSION);
		service.setGroup(group);

		// 暴露及注册服务
		service.export();
	}

}
